# -*- coding: utf-8 -*-
"""
Callbacks for filtering querysets by selected fields.

Usage::

    - the callback takes 2 arguments: the field itself and the queryset to
      manipulate 
      (and *field.value* is the current selected value for the field)
    - the callback must return the manipulated queryset
"""
from django.db.models import Q

from .. import utils

multicallbacks = utils.multicallbacks

def lookup_for(key):
    """
    Return a callback that will filter objects based on passed lookup *key*.
    """
    def callback(field, objects):
        return objects.filter(**{key: field.value})
    return callback
    
def lookup_for_letter(key, other="#"):
    """
    Return a callback that will filter objects based on the initial
    letter of the value of the field *key*.
    """
    def callback(field, objects):
        if field.value == other:
            lookup = {"%s__iregex" % key: "^[^a-z]"}
        else:
            lookup = {"%s__istartswith" % key: field.value}
        return objects.filter(**lookup)
    return callback
    
def lookup_for_boolean(key, true_value="yes"):
    """
    Return a callback that will filter objects based on passed boolean *key*
    and boolean mapping.
    """
    def callback(field, objects):
        value = field.value == true_value
        return objects.filter(**{key: value})
    return callback
    
# search callbacks

def in_fields(*args):
    """
    Callback factory for searches.
    The search is done using all fields passed as *args.
    """
    fields = list(args)
    def callback(field, objects):
        lookup = Q(**{"%s__icontains" % fields.pop(): field.value})
        for i in fields: 
            lookup = lookup | Q(**{"%s__icontains" % i: field.value})
        return objects.filter(lookup)
    return callback
    
# autocomplete callbacks

def from_queryset(queryset, field_name="name"):
    """
    Callback factory for search autocomplete.
    """
    def callback(q):
        lookup = {"%s__istartswith" % field_name: q}
        objects = queryset.order_by(field_name).filter(**lookup).distinct()
        return "\n".join(i[field_name] for i in objects.values(field_name))
    return callback
